Conception d'un document imprimable avec des outils Web
07/10/2020Dans l'univers des graphistes, on appel communément "print" tout ce qui a pour finalité d'être imprimé sur un bout de papier : plaquettes, affiches, coffrets, livrets. Je ne suis pas graphiste mais j'ai eu besoin de concevoir un lot de plaquettes destinées à l'impression. J'ai donc sorti mon navigateur...
Le document
Le document que je dois produire est une sorte de plaquette recto/verso au format carrée. Je ne connais pas encore les dimensions finales (cela dépendra du prix du papier, de l'impression et des enveloppes) mais on est à peu près sur du 14cm x 14cm.
L'agencement des plaquettes n'est pas super bien défini mais ça ressemble à une grille avec bordures blanches contenant des images et du texte.
Pour pimenter le tout, les images sont issues d'une banque d'images et choisis aléatoirement de sorte à ce que deux plaquettes ne possèdent pas les mêmes images. Au final, on aura alors autant de plaquettes différentes que de tirages.
Le principale problème : la résolution
Dans le monde de l'impression, lorsque l'on parle de résolution on parle de finesse d'impression et c'est un paramètre qui se défini en point par pouce (ppp ou dpi en anglais). Cela revient à parler de la capacité qu'a le materiel d'impression à inscrire les points d'encre sur un pouce (2,54cm).
Pour un rendu optimal, je cherche donc à faire correspondre le nombre de pixel du fichier à imprimer avec le nombre de point que la machine peut imprimer. Pour un document de 14,8cm de coté à 300dpi (standard utilisé dans l'impression), il faut donc générer un fichier de 1748 pixels de large.
- 300 dpi => 118,110236 point par cm
- 14,8 cm * 118,110236 = 1748 pixels
Pour vérifier mon calcul, je lance Gimp, je rentre la dimension (14,8cm), la résolution (300dpi) et il me calcul automatiquement 1748 pixels de large.
Coté production, je vais utilisé mon ordinateur avec un écran qui lui aussi à une résolution issu des capacités du matériel. Je ne parle pas ici de la taille/définition (1920x1080), mais du nombre de pixel par pouce, appelé aussi "pitch". Mon écran possède 96 pixels par pouce, à peu près 37,8 pixel par cm. Il y a donc à presque un ratio de 3 entre le rendu papier et le rendu sur mon ordinateur.
Le navigateur et les technologies Web
Le choix d'utiliser un navigateur peut paraître un peu exotique mais je ne vois que des avantages à me baser sur des technologies web pour produire ces documents.- Moteur de rendu du navigateur et CSS pour la mise en forme d'une grille HTML adpatative.
- Javascript pour le côté génération aléatoire des différentes plaquettes et pour l'extraction des en fichier imprimables.
Premier Test : Affichage d'une grille
Pour commencer, je vais pas me prendre la tête avec la bonne largeur, je vais commencer par créer une page HTML et m'appuyer sur Bootstrap 4 et le mode de dispostion flex pour réaliser la grille.
- La taille du cadre est fixé à 14,8cm par la variable CSS
--size
et est directement appliqué à l'élément de la classecadre
. - Le contenu (classe
content
) à une taille forcée à 100% de son contenu parent. - L'écartement des bordures est géré par la variable CSS
--padding-part
, fixé ici à 15px. - Pour bien aligner les paddings (colonnes côté à côte) on calcul une demi part de padding que l'on associe à des classe CSS
col-hp*
. - On utilise la classe
overflow-hidden
pour ne pas afficher la part de l'image qui déborde du conteneur parent. - Les images s'affichent à 100% de la largeur grâce à la classe
img
et s'adapte donc à la taille du cadre générale.
On remarque que l'élément créer par le navigateur fait 559px, le navigateur s'est basé sur ma résolution de 96dpi pour calculer 559px, en effet, 14,8cm * 37,8 = 559,44px.
Second Test : Taille en fonction de la résolution
Cette fois, on va essayer de rendre un peu plus paramétrique notre feuille de style CSS pour avoir un fonctionnement qui s'adapterai dans le cas où :
- Je choisi d'imprimer à 240dpi.
- La taille du papier physique change légérement et passe à 13cm.
En effet, pour éviter les problèmes de calcul on n'indique aucune unité sur tout ce qui est constantes et variables de configuration, on calcul des nombres et à la fin on applique une unité en multipliant par 1px.
Mon cadre fait maintenant 1228px, cela correspond parfaitement à 13cm à 240dpi.
Adapatation de la taille des textes et des bordures.
Désormais, le texte et le sous-texte sont clairement trop petit par rapport à la taille de la plaquette. De plus, les bordures de 15px paraissent trop fines par rapport aux images. On va mettre en place un système de ratio pour "adapter" les tailles en fonction du contexte.
On imagine les tailles des bordures et des textes pour une résolution de base (au mieux la résolution de son écran, dans mon cas 96dpi) et on appliquera le ratio en fonction de la résolution d'impression souhaitée.
Génération des plaquettes
Je ne vais pas trop m'attarder sur la technique, toutefois je me suis appuyé sur du code Javascript pour constituer à partir d'un ensemble d'images définis par tailles (horizontal, carré, vertical) des jeux d'association pour créer des plaquettes de manière aléatoire.
Ensuite j'ai utilisé l'excellente librairie Javascript Template7 pour générer les cadres à partir de deux templates Recto/Verso défini en HTML.
L'extraction en document imprimable
Bon, c'est bien sympa d'avoir une page HTML avec plein de plaquettes mais comment je les exploitent pour créer des documents imprimables ?
Dans un premier temps, on va utiliser domtoimage et plus précisemment un fork qui comprend plein de correctifs (notamment pour gérer l'importation des fonts google) domtoimagemore pour transformer les noeud HTML en Objet Canvas.
Ensuite on va exporter les Canvas en JPEG et les inclures dans un Zip (à l'aide de la librairie JSZIP) qui sera proposé en téléchargement à la fin du traitement.
Un petit exemple/prototype est testable à cette adresse, le code Javascript suivant est issu de cet exemple. Il comporte une plaquette recto/verso complète avec un bouton d'export positionné en bas de page.
Remarques importantes :
- La fonction
domtoimage.toJpeg
retourne un JPEG encodé sous forme de chaine de caractère en base 64 préfixé pardata:image/jpeg;base64,
. Ce préfixe est inutile pour constituer le fichier, il est écarté par l'étrangedataURI.substring(23)
. - Le compteur
cmpt
est utilisé pour lancer la procédure de demande de téléchargement du fichier Zip uniquement lorsque la dernière capture est faite. - La fonction
saveAs
provient de la biliothèque FileSaver.js et permet de sauvegarder à peu près tous types de fichier. - Pour que les ressources externes CSS puissent être importées dans le canvas, il convient de leur rajouter l'attribut
crossorigin="anonymous"
. Sans cela, les polices Googles (ou autre) et Bootstrap ne seraient pas intégrés au canvas.
Et voilà, on a nos images dans un Zip, y'a plus qu'à envoyer ça à l'imprimeur.
Conclusion
J'ai le sentiment d'avoir mieux compris la gestion des unités physiques (cm, mm, in) coté navigateur. Même si pour la conception d'interface Web, on préviligie plutôt des tailles en pourcentage combiné à des "breakpoints" en pixel, je pense qu'à partir du même principe on pourrait envisager un comportement CSS qui s'adapte parfaitement en fonction de la résolution du support qui le visualise.